﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using Cubicle.Core.Shared;

namespace Cubicle.Core.Processors
{

    public static class InstructionRequestExtensions
    {
        
        public const string TypeKey = "RequestType";
        public static void Type(this InstructionRequest target, RequestType value)
        {
            target.Set(TypeKey, value);
            target.RaisePropertyChanged(null, TypeKey);
        }
          
        public static RequestType Type(this InstructionRequest target)
        {
            return target.Get(TypeKey, RequestType.AllIncoming);
        }
        
        public const string ResultKey = "Result";
        public static object Result(this InstructionRequest target, object value = null)
        {
            if (value == null) return target.Get<object>(ResultKey, null);
            target.Set(ResultKey, value);
            target.RaisePropertyChanged(null, ResultKey);
            return value;
        }

        public static InstructionRequest Complete(this InstructionRequest target, object result)
        {
            target.Result(result);
            target.Type(RequestType.Completed);
            return target;
        }

        public static void Fail(this InstructionRequest target, string message, params object[] args)
        {
            InstructionRequest.Logger.Error(message, args);
            target.Type(RequestType.Failed);
        }

        public const string ProgressKey = "Progress";
        public static void Progress(this InstructionRequest target, double value)
        {
            target.Set(ProgressKey, value);
            target.RaisePropertyChanged(null, ProgressKey);
        }
          
        public static double Progress(this InstructionRequest target)
        {
            return target.Get<double>(ProgressKey, 0);
        }
               
    }

    public class InstructionRequest : DynamicItem
    {
        // Nlog
        public static NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();

        // Instruction data
        public int Id = 0;
        public object Target = null;
        public Type TargetType = null;
        public Instruction Inst;
        public int ParameterCount = 0;
        public int CandidateCount = 0;
        public IEnumerable<MemberInfo> Candidates = null;
        public MethodInfo TargetMethod = null;
        public FieldInfo TargetField = null;
        public ConstructorInfo TargetConstructor = null;
        public PropertyInfo TargetProperty = null;
        public object[] Parameters = null;
        public bool IsGenericMethodInvoke = false;
        public Exception ExceptionInfo = null;
        public ParameterInfo[] IndexParameters = null;
        public Thread ExecutingThread;

        public InstructionRequest(Instruction inst)
        {
            Inst = inst;
        }

    }
}